/**
 * Created by XianTao on 2016/11/14
 * <p/>
 * Copyright (c) 2015-2015
 * Apache License
 * Version 2.0, January 2004
 * http://www.apache.org/licenses/
 */
package org.lego.biz.wechat.lechuan.mobile.api.service;

import com.aspire.portal.web.security.client.GenerateSignature;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.lego.util.DateTimeUtil;
import org.springframework.stereotype.Service;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Service
@Slf4j
public class ThirdPartService {
    private static final String CHARSET = "UTF-8";

    /**
     * 充值内蒙古移动流量到流量币平台
     *
     * @param tel    充值手机号码
     * @param number 充值数量
     * @return 充值结果message
     */
    public String convert2LiuLiangJia(String tel, Integer number) {
        if (number == null || number <= 0) {
            return "充值数量为" + (number == null ? "null" : number);
        }
        String dateTime = DateTimeUtil.getFullDateTime(DateTimeUtil.getCurrentTimeMillis());
        Map<String, String> paramMap = new HashMap<String, String>();
        paramMap.put("portalType", "WAP"); //正式
        paramMap.put("portalID", "hongpcb");    //正式
        paramMap.put("company_code", "hongpcb"); //正式的合作企业编码
        paramMap.put("transactionID", dateTime + UUID.randomUUID().toString().substring(0, 8));    //交易唯一编码：yyyyMMddHHmmss+8位唯一序号
        paramMap.put("method", "companyCreditHandsel");
        paramMap.put("msisdn", tel); //手机号码
        paramMap.put("credit", String.valueOf(number)); //流量币数量
        paramMap.put("oper_time", dateTime);

        StringBuilder sb = new StringBuilder();
        String urlStr = "http://nm.liuliangjia.cn:20870/openapi/v2.0";  //正式服务器
        String keyPath = "/mnt/lechuan/private.key"; //正式服务器上的key

        String json = post(urlStr, paramMap, keyPath, null, null);
        String resultMessage = "";
        try {
            Map resultMap = new ObjectMapper().readValue(json, Map.class);
            resultMessage = (String) resultMap.get("message");
        } catch (Exception e) {
            resultMessage = e.getMessage();
        }
        return resultMessage;
    }

    private String post(String url, Map<String, String> queryParas, String keyPath, String data, Map<String, String> headers) {
        HttpURLConnection conn = null;
        try {
            String urlWithParams = buildUrlWithQueryString(url, queryParas, keyPath);
            log.info("开始post请求：{}", urlWithParams);
            conn = getHttpConnection(urlWithParams, "POST", headers);
            conn.connect();
            OutputStream out = conn.getOutputStream();
            if (notBlank(data)) {
                out.write(data.getBytes(CHARSET));
            }
            out.flush();
            out.close();
            String result = readResponseString(conn);
            log.info("返回结果：{}", result);
            return result;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
    }

    private String buildUrlWithQueryString(String url, Map<String, String> queryParas, String keyPath) {
        if (queryParas == null || queryParas.isEmpty())
            return url;

        StringBuilder sb = new StringBuilder(url);
        boolean isFirst;
        if (!url.contains("?")) {
            isFirst = true;
            sb.append("?");
        } else {
            isFirst = false;
        }

        for (Map.Entry<String, String> entry : queryParas.entrySet()) {
            if (isFirst) {
                isFirst = false;
            } else {
                sb.append("&");
            }

            String key = entry.getKey();
            String value = entry.getValue();
            if (notBlank(value)) {
                try {
                    value = URLEncoder.encode(value, CHARSET);
                    sb.append(key).append("=").append(value);
                } catch (UnsupportedEncodingException e) {
                    throw new RuntimeException(e);
                }
            }
        }

        //加上签名
        sb.append("&").append("sign").append("=").append(getSign(queryParas, keyPath));

        return sb.toString();
    }

    private HttpURLConnection getHttpConnection(String url, String method, Map<String, String> headers)
            throws IOException, NoSuchAlgorithmException, NoSuchProviderException, KeyManagementException {
        URL _url = new URL(url);
        HttpURLConnection conn = (HttpURLConnection) _url.openConnection();

        conn.setRequestMethod(method);
        conn.setDoOutput(true);
        conn.setDoInput(true);

        conn.setConnectTimeout(19000);
        conn.setReadTimeout(19000);

        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36");

        if (headers != null && !headers.isEmpty())
            for (Map.Entry<String, String> entry : headers.entrySet())
                conn.setRequestProperty(entry.getKey(), entry.getValue());

        return conn;
    }

    private String readResponseString(HttpURLConnection conn) {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        try {
            inputStream = conn.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, CHARSET));
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line).append("\n");
            }
            return sb.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private String getSign(Map<String, String> queryParas, String keyPath) {
        // 对参数名进行字典排序
        String[] keyArray = queryParas.keySet().toArray(new String[0]);
        Arrays.sort(keyArray);

        StringBuilder sb = new StringBuilder();
        boolean isFirst = true;
        for (String key : keyArray) {
            String value = queryParas.get(key);
            if (notBlank(value)) {
                if (isFirst) {
                    isFirst = false;
                } else {
                    sb.append("&");
                }
                sb.append(key).append("=").append(value);
            }
        }
        return new GenerateSignature().sign(sb.toString(), keyPath);
    }

    private boolean notBlank(String str) {
        return !(str == null || "".equals(str.trim()) || "null".equals(str.trim()));
    }
}
